package com.dtguai.web.common.exception;

import com.dtguai.web.common.error.ErrorCode;
import com.dtguai.web.util.IpUtils;
import com.dtguai.web.util.redis.RedisUtil;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * @author: guoLiang
 * @date：2018-09-29 03:46:03
 * @类描述：异常处理器
 */
@RestControllerAdvice
public class DefinedExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private final String BLACKLIST_IP_HASH_KEY = "blacklist_ip_hash_key";

    @Autowired
    RedisUtil redisUtil;

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(DefinedException.class)
    public DefinedMap handleDefinedException(DefinedException e) {
        DefinedMap dm = new DefinedMap();
        dm.put("code", e.getCode());
        dm.put("msg", e.getMessage());
        return dm;
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public DefinedMap handlerNoFoundException(Exception e, HttpServletRequest request) {
        String ip = IpUtils.getIpAddress(request);
        Object cnt = redisUtil.getHash(BLACKLIST_IP_HASH_KEY, ip);
        Integer cntInt = cnt == null ? 0 : Integer.parseInt(cnt.toString());
        redisUtil.setHash(BLACKLIST_IP_HASH_KEY, ip, cntInt + 1, RedisUtil.TIME_OUT_DAY);
        logger.error(ip + "----" + e.getMessage(), ip + "----" + e);
        return DefinedMap.error(ErrorCode.NOT_FOUND);
    }

    @ExceptionHandler(DuplicateKeyException.class)
    public DefinedMap handleDuplicateKeyException(DuplicateKeyException e) {
        logger.error(e.getMessage(), e);
        return DefinedMap.error(ErrorCode.REPETITION);
    }

    @ExceptionHandler(Exception.class)
    public DefinedMap handleException(Exception e) {
        logger.error(e.getMessage(), e);
        return DefinedMap.error();
    }

    @ExceptionHandler(AuthorizationException.class)
    public DefinedMap handleAuthorizationException(AuthorizationException e) {
        logger.error(e.getMessage(), e);
        return DefinedMap.error(ErrorCode.NOT_PERMISSION);
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public DefinedMap handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        logger.info(e.getMessage(), e);
        return DefinedMap.error(ErrorCode.HTTP_REQUEST_METHOD_NOT_SUPPORTED);
    }

    @ExceptionHandler(UnauthorizedException.class)
    public DefinedMap handleUnauthorizedException(UnauthorizedException e) {
        logger.info(e.getMessage(), e);
        return DefinedMap.error(ErrorCode.NOT_PERMISSION);
    }

}
